import { Component, OnInit, OnDestroy, ViewChild, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { PageHeaderModule } from '@delon/abc/page-header';
import { STColumn, STModule } from '@delon/abc/st';
import { DelonACLModule } from '@delon/acl';
import {
  DelonFormModule,
  SFComponent,
  SFRadioWidgetSchema,
  SFSchema,
  SFSchemaEnumType,
  SFSelectWidgetSchema,
  SFUISchema
} from '@delon/form';
import type { SFColorWidgetSchema } from '@delon/form/widgets/color';
import { _HttpClient, ModalHelper } from '@delon/theme';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzCardModule } from 'ng-zorro-antd/card';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzGridModule } from 'ng-zorro-antd/grid';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzRadioModule } from 'ng-zorro-antd/radio';
import { NzFormatEmitEvent, NzTreeModule } from 'ng-zorro-antd/tree';
import { catchError, map, Observable } from 'rxjs';
import { Api } from 'src/app/shared/api/api';
import { BaseAbilityComponent } from 'src/app/shared/base.ability.component';
import {
  DELETED_STATUS_BADGE,
  DELETED_STATUS_ENUM,
  MENU_GRAD_ENMU,
  MENU_TYPE_ENUM,
  USER_LABEL_ENUM
} from 'src/app/shared/constant/common-constant';
import { ResponseCode } from 'src/app/shared/response.code';

import { IconModalComponent } from './icon-modal.component';
import { MenuPermissionEditComponent } from './menu-permission-edit.component';

@Component({
  selector: 'app-system-menu',
  templateUrl: './menu.component.html',
  imports: [
    PageHeaderModule,
    NzGridModule,
    NzCardModule,
    NzTreeModule,
    NzRadioModule,
    FormsModule,
    DelonACLModule,
    DelonFormModule,
    NzIconModule,
    STModule,
    NzButtonModule,
    NzIconModule
  ]
})
export class SystemMenuComponent extends BaseAbilityComponent implements OnInit, OnDestroy {
  deletedtatus: NzSafeAny[] = [];
  currentMenuType: NzSafeAny = 0;
  currentMenu: NzSafeAny = {};
  currentMenuPermissions: NzSafeAny[] = [];
  currentMenuFiler = 'false';
  currentPermissionFilter = 'false';
  allNodes: NzSafeAny[] = [];
  nodes: NzSafeAny[] = [];
  selectedNodes: NzSafeAny[] = [];
  schema: SFSchema = {
    properties: {}
  };

  ui: SFUISchema = {
    '*': {
      spanLabel: 6,
      spanControl: 18,
      grid: { span: 12 }
    }
  };

  @ViewChild('sf', { static: false }) private sf!: SFComponent;

  permissionColmuns: STColumn[] = [
    { title: '序号', type: 'no', width: 60 },
    { title: '权限', index: 'permission' },
    { title: '备注', index: 'remark' },
    { title: '状态', index: 'deleted', type: 'badge', badge: DELETED_STATUS_BADGE, width: 100 },
    {
      title: '操作',
      width: 150,
      buttons: [
        {
          text: '编辑',
          icon: 'edit',
          click: (record: NzSafeAny) => {
            this.editPermission(record);
          },
          iif: this.currentMenu && this.currentMenu.id && !this.currentMenu.deleted,
          acl: { ability: ['edit'] }
        },
        {
          text: '删除',
          icon: 'delete',
          click: (record: NzSafeAny) => {
            this.deletePermission(record);
          },
          acl: { ability: ['delete'] }
        }
      ]
    }
  ];
  private readonly http = inject(_HttpClient);
  private readonly modal = inject(ModalHelper);
  private readonly modalService = inject(NzModalService);
  private readonly msg = inject(NzMessageService);

  ngOnInit() {
    super.initAbilities();
    this.init();
    this.queryMenuTree();
  }

  ngOnDestroy(): void {
    super.clearAbilities();
  }

  init() {
    this.deletedtatus = DELETED_STATUS_ENUM.filter(item => item.value !== null);
    const acls = [{ label: '超管', value: 'super' }].concat(USER_LABEL_ENUM.filter(item => item.value !== ''));
    this.schema = {
      properties: {
        text: { type: 'string', title: '名称' },
        key: { type: 'string', title: '编码' },
        iconInfo: {
          type: 'string',
          title: '图标',
          ui: {
            widget: 'custom'
          }
        },
        fill: {
          type: 'string',
          title: '图标颜色',
          ui: {
            widget: 'color',
            showText: true,
            defaultValue: '#1890FF',
            change: (value: NzSafeAny) => this.resetIconColor(value)
          } as SFColorWidgetSchema
        },
        link: { type: 'string', title: '地址' },
        acl: {
          type: 'string',
          title: 'acl',
          enum: acls,
          default: 'operator',
          ui: {
            widget: 'select',
            mode: 'multiple'
          } as SFSelectWidgetSchema
        },
        grade: {
          type: 'string',
          title: '级别',
          enum: MENU_GRAD_ENMU,
          default: '15'
        },
        module: {
          type: 'string',
          title: '所属应用',
          default: '0',
          ui: {
            widget: 'select',
            asyncData: () => this.allApplicationList()
          } as SFSelectWidgetSchema
        },
        type: {
          type: 'string',
          title: '类型',
          enum: MENU_TYPE_ENUM,
          default: 0,
          ui: {
            spanLabel: 3,
            spanControl: 21,
            widget: 'radio',
            styleType: 'button',
            buttonStyle: 'solid',
            grid: {
              span: 24
            }
          } as SFRadioWidgetSchema
        },
        rank: { type: 'number', title: '排序', maximum: 32767, minimum: -32768 },
        deleted: {
          type: 'string',
          title: '状态',
          enum: this.deletedtatus,
          default: false,
          ui: {
            widget: 'radio',
            styleType: 'button',
            buttonStyle: 'solid'
          } as SFRadioWidgetSchema
        },
        i18n: { type: 'string', title: 'i18n主键' },
        group: { type: 'boolean', title: '显示分组名' },
        linkExact: { type: 'boolean', title: '外链' },
        externalLink: { type: 'string', title: '外部连接' },
        target: {
          type: 'string',
          title: '打开方式',
          enum: [
            { label: '_blank', value: '_blank' },
            { label: '_self', value: '_self' },
            { label: '_parent', value: '_parent' },
            { label: '_top', value: '_top' }
          ]
        },
        icon: {
          type: 'string',
          title: '图标',
          ui: {
            hidden: true
          }
        },
        disabled: { type: 'boolean', title: '注销' },
        hide: { type: 'boolean', title: '隐藏' },
        hideInBreadcrumb: { type: 'boolean', title: '面包屑中隐藏' },
        shortcut: { type: 'boolean', title: '快捷方式' },
        shortcutRoot: { type: 'boolean', title: '根快捷方式' },
        reuse: { type: 'boolean', title: '重用' },
        open: { type: 'boolean', title: '打开' },
        parentId: { type: 'string', title: '父节点', ui: { hidden: true } }
      },
      required: ['text', 'key', 'acl']
    };
  }

  allApplicationList(): Observable<SFSchemaEnumType> {
    return this.http.get(`${Api.BaseSysApplicationApi}/list`, { deleted: false }).pipe(
      map((res: NzSafeAny) => {
        const temp = [{ label: '平台', value: '0' }];
        res.data?.forEach((item: NzSafeAny) => {
          temp.push({ label: item.name, value: item.code });
        });
        return temp;
      }),
      catchError(error => {
        throw new Error(error);
      })
    );
  }
  getTypleList(): Array<{ label: string; value: number }> {
    return MENU_TYPE_ENUM;
  }

  menuClick(event: NzFormatEmitEvent): void {
    const menu = event.node?.origin['menu'];
    if (menu) {
      menu.iconInfo = { value: menu.icon, fill: menu.fill };
      this.currentMenu = menu;
      const temp: NzSafeAny = [event.node?.origin.key];
      this.selectedNodes = temp;
      if (this.currentMenu.id) {
        this.queryPermission();
      } else {
        this.currentMenuPermissions = [];
      }
    } else {
      this.currentMenu = undefined;
    }
  }

  filterMenuTree(e: NzSafeAny) {
    this.currentMenu = undefined;
    const temp = JSON.parse(JSON.stringify(this.allNodes));
    // 第0个是根元素
    temp[0].children = temp[0].children.filter((item: NzSafeAny) => item.menu.type === e);
    this.nodes = temp;
  }

  queryMenuTree() {
    let params: NzSafeAny = {};
    if (this.currentMenuFiler) {
      params.deleted = this.currentMenuFiler === 'true';
    }
    let temp: NzSafeAny = [
      {
        title: '根菜单',
        key: '-1',
        expanded: true
      }
    ];
    this.http.get(`${Api.BaseAntMenuApi}/tree`, params).subscribe((res: NzSafeAny) => {
      if (res && res.code === ResponseCode.SUCCESS) {
        if (!res.data || res.data.length < 1) {
          this.nodes = temp;
          return;
        }
        temp[0].children = res.data;
        this.selectedNodes = [];
        if (this.currentMenu && this.currentMenu.id) {
          this.selectedNodes = [this.currentMenu.id];
        }
        this.allNodes = temp;
        this.nodes = temp;
        this.filterMenuTree(this.currentMenuType);
      } else {
        this.nodes = temp;
      }
    });
  }

  queryPermission() {
    let params: NzSafeAny = {};
    if (this.currentPermissionFilter) {
      params.deleted = this.currentPermissionFilter === 'true';
    }
    this.http.get(`${Api.BaseSysMenuPermissionApi}/menu/${this.currentMenu.id}`, params).subscribe((res: NzSafeAny) => {
      if (res && res.code === ResponseCode.SUCCESS) {
        if (!res.data) {
          this.currentMenuPermissions = [];
          return;
        }
        this.currentMenuPermissions = res.data;
      } else {
        this.currentMenuPermissions = [];
      }
    });
  }

  add() {
    let temp: NzSafeAny = { parentId: '0', acl: [] };
    if (this.currentMenu && this.currentMenu.id) {
      temp.parentId = this.currentMenu.id;
    }
    this.currentMenu = temp;
  }

  choseIcon() {
    const iconModal = this.modalService.create({
      nzTitle: '选择图标',
      nzContent: IconModalComponent,
      nzData: {},
      nzWidth: 950,
      nzFooter: null
    });
    iconModal.afterClose.subscribe((result: NzSafeAny) => this.setIcon(result));
  }

  deleteIcon() {
    if (this.sf) {
      this.sf.setValue('/iconInfo', {});
      this.sf.setValue('/icon', null);
      this.sf.setValue('/fill', null);
    }
  }

  setIcon(icon: NzSafeAny) {
    console.log(icon);
    if (this.sf) {
      this.sf.setValue('/icon', icon);
      const fill = this.sf.getValue('/fill');
      if (fill) this.sf.setValue('/iconInfo', { value: icon, fill: fill });
      else this.sf.setValue('/iconInfo', { value: icon });
    }
  }

  resetIconColor(ev: NzSafeAny): void {
    if (this.sf) {
      const icon = this.sf.getValue('/icon');
      if (icon) this.sf.setValue('/iconInfo', { value: icon, fill: ev });
      else this.sf.setValue('/iconInfo', { fill: ev });
    }
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  formValueChange(event: NzSafeAny) {
    // console.log(event);
  }

  reset(event: NzSafeAny) {
    let temp: NzSafeAny = { parentId: '0' };
    if (event.parentId) {
      temp.parentId = event.parentId;
    }
    this.currentMenu = temp;
  }

  menuDrag(event: NzSafeAny) {
    // TODO 拖动排序
    this.msg.warning('开发中');
    if (event && event.dragNode) {
      // const origin = event.dragNode.origin;
      // const parent = event.dragNode.parentNode.origin;
      console.log('待排序');
    }
  }

  save(value: NzSafeAny) {
    let data = { ...value };
    delete data.iconInfo;
    if (this.currentMenu.id) {
      this.http.put(Api.BaseAntMenuApi, data).subscribe((res: NzSafeAny) => {
        if (res) {
          if (res.code === ResponseCode.SUCCESS) {
            this.msg.success('修改成功');
            this.queryMenuTree();
          } else {
            this.msg.warning(res.message);
          }
        } else {
          this.msg.error('修改失败，未知错误');
        }
      });
    } else {
      this.http.post(Api.BaseAntMenuApi, data).subscribe((res: NzSafeAny) => {
        if (res) {
          if (res.code === ResponseCode.SUCCESS) {
            this.msg.success('保存成功');
            this.queryMenuTree();
          } else {
            this.msg.warning(res.message);
          }
        } else {
          this.msg.error('保存失败，未知错误');
        }
      });
    }
  }

  addPermission() {
    this.modal
      .createStatic(MenuPermissionEditComponent, { menuId: this.currentMenu.id }, { size: 'md', drag: true })
      .subscribe(() => this.queryPermission());
  }

  editPermission(permission: NzSafeAny) {
    this.modal.createStatic(MenuPermissionEditComponent, permission, { size: 'md', drag: true }).subscribe(() => this.queryPermission());
  }

  deletePermission(permission: NzSafeAny) {
    this.modalService.confirm({
      nzTitle: '确定删除吗?',
      nzContent: '<b style="color: red;">如果您确定要删除请点击确定按钮，否则点取消</b>',
      nzOkText: '确定',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: () =>
        this.http.delete(`${Api.BaseSysMenuPermissionApi}/${permission.id}`).subscribe((res: NzSafeAny) => {
          if (res) {
            if (res.code === ResponseCode.SUCCESS) {
              this.queryPermission();
              this.msg.success('删除成功');
            } else {
              this.msg.warning(res.message);
            }
          } else {
            this.msg.error('删除失败，未知错误');
          }
        }),
      nzCancelText: '取消',
      nzOnCancel: () => console.log('Cancel')
    });
  }
}
